package com.origin.chaos.chat.core.service.impl;

import com.origin.chaos.chat.bean.ChaosMessage;
import com.origin.chaos.chat.bean.vo.ChaosMessages;
import com.origin.chaos.chat.core.service.ChatService;
import com.origin.chaos.common.util.ObjectUtil;
import com.origin.chaos.security.bean.LoginUser;
import com.origin.chaos.security.serivce.IUserService;
import com.origin.chaos.security.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author: tao.ding
 * @date 2021-08-17
 */
@Service
@Slf4j
public class ChatServiceImpl implements ChatService {
    /**
     * 聊天室消息列表键
     */
    private static final String MESSAGE_LIST_KEY = "messages";

    private StringRedisTemplate stringRedisTemplate;

    private SimpMessagingTemplate messagingTemplate;

    private IUserService userService;

    @Override
    public void sendMessage(String message) {
        LoginUser loginUser = TokenUtil.getCurrentLoginUser();
        ChaosMessage chaosMessage = new ChaosMessage();
        chaosMessage.setUserId(loginUser.getId());
        chaosMessage.setMessage(message);
        chaosMessage.setNickName(loginUser.getNickName());
        chaosMessage.setTimestamp(System.currentTimeMillis());
        this.stringRedisTemplate.opsForList().rightPush(MESSAGE_LIST_KEY, chaosMessage.toRedisStr());
//      发送websocket消息
        this.messagingTemplate.convertAndSend("/topic/chat-message", chaosMessage);
    }

    @Override
    public ChaosMessages reverseSearchMessageList(boolean firstPage, long index, long size) {
        long start, end;
        if (firstPage) {
            // 首次查询
            long messageNum = ObjectUtil.ofLong(this.stringRedisTemplate.opsForList().size(MESSAGE_LIST_KEY));
            if (messageNum == 0) {
                return ChaosMessages.empty();
            }
            end = messageNum - 1;
        } else {
            // 后续查询
            end = index;
        }
        start = Math.max(0, end - size + 1);
        List<ChaosMessage> messages = Optional.ofNullable(this.stringRedisTemplate.opsForList().range(MESSAGE_LIST_KEY, start, end))
                .orElse(Collections.emptyList())
                .stream().map(x -> {
                    ChaosMessage message = ChaosMessage.ofRedisStr(x);
                    message.setNickName(this.userService.getUserOpenInfoById(message.getUserId()).getNickName());
                    return message;
                }).collect(Collectors.toList());
        ChaosMessages res = new ChaosMessages();
        res.setMessages(messages);
        res.setNextIndex(Math.max(-1, start - 1));
        return res;
    }

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Autowired
    public void setMessagingTemplate(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @Autowired
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }
}
